package com.zhuanzhuan.hero.user.facade;

import com.bj58.spat.scf.server.contract.annotation.ServiceBehavior;
import com.bj58.youpin.common.rpc.result.Result;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhuanzhuan.hero.user.consts.NumConsts;
import com.zhuanzhuan.hero.user.dto.backend.*;
import com.zhuanzhuan.hero.user.dto.label.QueryBrandModelLabelDTO;
import com.zhuanzhuan.hero.user.entity.HeroLabelInfo;
import com.zhuanzhuan.hero.user.entity.HeroUserAudit;
import com.zhuanzhuan.hero.user.enums.*;
import com.zhuanzhuan.hero.user.exception.BusinessException;
import com.zhuanzhuan.hero.user.pojo.bo.*;
import com.zhuanzhuan.hero.user.pojo.po.QueryBusinessLabelRelatePO;
import com.zhuanzhuan.hero.user.pojo.po.UserPO;
import com.zhuanzhuan.hero.user.service.HeroLabelInfoService;
import com.zhuanzhuan.hero.user.service.HeroUserAuditService;
import com.zhuanzhuan.hero.user.service.HeroUserInfoService;
import com.zhuanzhuan.hero.user.service.HeroUserLabelRelationService;
import com.zhuanzhuan.hero.user.util.Assert;
import com.zhuanzhuan.hero.user.util.StringUtil;
import com.zhuanzhuan.hero.user.vo.PageResultWrapper;
import com.zhuanzhuan.hero.user.vo.backend.QueryAuditListVO;
import com.zhuanzhuan.hero.user.vo.backend.QueryBusinessLabelListVO;
import com.zhuanzhuan.hero.user.vo.backend.QueryBusinessLabelRelateVO;
import com.zhuanzhuan.hero.user.vo.backend.QueryUserListVO;
import com.zhuanzhuan.hero.user.vo.label.BatchRelateBusinessLabelVO;
import com.zhuanzhuan.hero.user.vo.label.LabelInfoVO;
import com.zhuanzhuan.hero.user.vo.label.LevelLabelVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @ClassName ManagementBackendFacadeImpl
 * @Description
 * @Author hanjunjun
 * @Date 2024/6/29 15:10
 */
@ServiceBehavior
@Slf4j
public class ManagementBackendFacadeImpl implements IManagementBackendFacade {

    @Resource
    private HeroUserAuditService userAuditService;

    @Resource
    private HeroLabelInfoService labelInfoService;

    @Resource
    private HeroUserLabelRelationService userLabelRelationService;

    @Resource
    private HeroUserInfoService userInfoService;

    @Override
    public Result<PageResultWrapper<QueryUserListVO>> pageUser(QueryUserListDTO queryUserListDTO) {
        QueryUserInfoParam queryParam = new QueryUserInfoParam();
        List<Integer> memberLevels = queryUserListDTO.getMemberLevels();
        queryParam.setUids(queryUserListDTO.getUids())
            .setNickname(queryUserListDTO.getNickname())
            .setRegisMobiles(queryUserListDTO.getMobiles())
            .setUserStates(queryUserListDTO.getUserStates())
            .setMemberLevels(memberLevels).setSettleTimeStart(queryUserListDTO.getSettleTimeStart())
            .setSettleTimeEnd(queryUserListDTO.getSettleTimeEnd());
        if (CollectionUtils.isNotEmpty(memberLevels) && memberLevels.contains(QueryUserListDTO.NO_MEMBER_LEVEL)) {
            queryParam.setNoMember(true);
        }

        PageInfo<UserPO> pageInfo = PageHelper.startPage(queryUserListDTO.getPageNum(), queryUserListDTO.getPageSize())
            .doSelectPageInfo(() -> userInfoService.listByParam(queryParam));
        List<UserPO> list = pageInfo.getList();
        if (CollectionUtils.isEmpty(list)) {
            return Result.success(PageResultWrapper.empty(queryUserListDTO));
        }

        List<QueryUserListVO> voList = list.stream().map(this::convertQueryUserListVO).collect(Collectors.toList());

        return Result.success(PageResultWrapper.wrapper(pageInfo.getTotal(), voList, pageInfo.isHasNextPage(), queryUserListDTO));
    }

    @Override
    public Result<PageResultWrapper<QueryBusinessLabelListVO>> pageBusinessLabel(
        @Valid QueryBusinessLabelListDTO queryDTO) {
        LabelInfoQueryBO queryBO =
            LabelInfoQueryBO.builder().labelType(LabelTypeEnum.BUSINESS.getCode()).createUid(queryDTO.getCreaterId())
                .labelName(queryDTO.getLabelName()).labelStates(queryDTO.getLabelStates())
                .createTimeStart(queryDTO.getCreateTimeStart()).createTimeEnd(queryDTO.getCreateTimeEnd())
                .build();

        PageInfo<HeroLabelInfo> pageInfo = PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize())
            .doSelectPageInfo(() -> labelInfoService.listByParam(queryBO));
        List<HeroLabelInfo> list = pageInfo.getList();
        if (CollectionUtils.isEmpty(list)) {
            return Result.success(PageResultWrapper.empty(queryDTO));
        }

        //单独查询标签关联数 赋值
        List<Long> labelIds = list.stream().map(HeroLabelInfo::getId).distinct().collect(Collectors.toList());
        Map<Long, Integer> labelsRelatedNumMap = labelInfoService.queryLabelsRelatedNum(labelIds);
        list.forEach(label -> {
            label.setRelatedNum(labelsRelatedNumMap.getOrDefault(label.getId(), NumConsts.ZERO));
        });

        List<QueryBusinessLabelListVO> voList = list.stream().map(this::convertLabelVO).collect(Collectors.toList());

        return Result.success(PageResultWrapper.wrapper(pageInfo.getTotal(), voList, pageInfo.isHasNextPage(), queryDTO));
    }

    @Override
    public Result<PageResultWrapper<QueryBusinessLabelRelateVO>> pageBusinessLabelRelate(
        QueryBusinessLabelRelateDTO queryDTO) {
        QueryUserLabelRelateBO query = new QueryUserLabelRelateBO(queryDTO.getLabelId(), queryDTO.getUid(), queryDTO.getMobile());
        //不生效的关联关系也要查出来
        query.setStates(Arrays.asList(StateEnum.EFFECTIVE.getCode(), StateEnum.INVALID.getCode()));
        query.setLabelType(LabelTypeEnum.BUSINESS.getCode());

        PageInfo<QueryBusinessLabelRelatePO> pageInfo = PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize())
            .doSelectPageInfo(() -> userLabelRelationService.queryByParam(query));
        List<QueryBusinessLabelRelatePO> list = pageInfo.getList();
        if (CollectionUtils.isEmpty(list)) {
            return Result.success(PageResultWrapper.empty(queryDTO));
        }

        //查询标签
        List<Long> labelIds =
            list.stream().map(QueryBusinessLabelRelatePO::getLabelId).distinct().collect(Collectors.toList());
        Map<Long, HeroLabelInfo> labelIdMap = labelInfoService.listById(labelIds).stream()
            .collect(Collectors.toMap(HeroLabelInfo::getId, Function.identity()));

        List<QueryBusinessLabelRelateVO> voList =
            list.stream().map(po -> this.convertQueryBusinessLabelRelateVO(po, labelIdMap.get(po.getLabelId())))
                .collect(Collectors.toList());

        return Result.success(PageResultWrapper.wrapper(pageInfo.getTotal(), voList, pageInfo.isHasNextPage(), queryDTO));
    }

    @Override
    public Result<Void> cancelBusinessLabelRelate(@Valid CancelBusinessLabelRelateDTO cancelBusinessLabelRelateDTO) {
        Long labelId = cancelBusinessLabelRelateDTO.getLabelId();
        HeroLabelInfo labelInfo = labelInfoService.queryById(labelId);
        Assert.notNull(labelInfo);

        Long uid = cancelBusinessLabelRelateDTO.getToUid();
        userLabelRelationService.delByUidsAndLabelId(Collections.singletonList(uid), labelInfo,
            cancelBusinessLabelRelateDTO.getOperaterUid());

        return Result.success();
    }

    @Override
    public Result<BatchRelateBusinessLabelVO> batchRelateBusinessLabel(@Valid RelateBusinessLabelDTO relateBusinessLabelDTO) {
        HeroLabelInfo labelInfo = labelInfoService.queryById(relateBusinessLabelDTO.getLabelId());
        Assert.notNull(labelInfo, ExceptionMsgEnum.BUSINESS_ERROR);
        if (!LabelTypeEnum.BUSINESS.getCode().equals(labelInfo.getLabelType())) {
            throw new BusinessException(ExceptionMsgEnum.PARAM_ERROR);
        }

        BatchRelateBusinessLabelVO resultVO =
            userLabelRelationService.labelRelateUsers(labelInfo, relateBusinessLabelDTO);

        return Result.success(resultVO);
    }

    @Override
    public Result<Void> switchStateBusinessLabel(SwitchStateBusinessLabelDTO switchStateBusinessLabelDTO) {
        labelInfoService.switchEffective(switchStateBusinessLabelDTO.getLabelId(), switchStateBusinessLabelDTO.getLabelState(),
            switchStateBusinessLabelDTO.getOperaterUid(), switchStateBusinessLabelDTO.getOperateTime());

        return Result.success();
    }

    @Override
    public Result<Void> createBusinessLabel(@Valid CreateBusinessLabelDTO createBusinessLabelDTO) {
        LabelInfoQueryBO labelQuery = LabelInfoQueryBO.builder().labelType(LabelTypeEnum.BUSINESS.getCode())
            .labelName(createBusinessLabelDTO.getLabelName()).build();

        List<HeroLabelInfo> labelInfos = labelInfoService.listByParam(labelQuery);
        if (CollectionUtils.isNotEmpty(labelInfos)) {
            throw new BusinessException("该标签已存在");
        }

        CreateLabelBO createLabelBO = new CreateLabelBO();
        createLabelBO.setLabelType(LabelTypeEnum.BUSINESS.getCode())
            .setLabelName(createBusinessLabelDTO.getLabelName())
            .setLabelIcon(createBusinessLabelDTO.getLabelIcon())
            .setCreaterRole(CreaterRoleEnum.BUSINESS.getCode())
            //默认是未启用
            .setLabelState(LabelStateEnum.INVALID.getCode())
            .setCreaterUid(createBusinessLabelDTO.getOperaterUid())
            .setCreateTime(createBusinessLabelDTO.getOperateTime());
        labelInfoService.createLabel(createLabelBO);

        return Result.success();
    }

    @Override
    public Result<PageResultWrapper<QueryAuditListVO>> pageAuditRecord(@Valid QueryAuditListDTO queryAuditListDTO) {
        QueryAuditParam queryAuditParam = new QueryAuditParam();
        BeanUtils.copyProperties(queryAuditListDTO, queryAuditParam);

        PageInfo<HeroUserAudit> pageInfo =
            PageHelper.startPage(queryAuditListDTO.getPageNum(), queryAuditListDTO.getPageSize())
                .doSelectPageInfo(() -> userAuditService.listByParam(queryAuditParam));
        List<HeroUserAudit> list = pageInfo.getList();
        if (CollectionUtils.isEmpty(list)) {
            return Result.success(PageResultWrapper.empty(queryAuditListDTO));
        }

        List<QueryAuditListVO> voList = list.stream().map(this::convertQueryAuditListVO).collect(Collectors.toList());
        return Result.success(PageResultWrapper.wrapper(pageInfo.getTotal(), voList, pageInfo.isHasNextPage(), queryAuditListDTO));
    }

    @Override
    public Result<Void> operateAudit(@Valid AuditOperateDTO auditOperateDTO) {
        HeroUserAudit userAudit = userAuditService.queryById(auditOperateDTO.getAuditId());
        Assert.notNull(userAudit, ExceptionMsgEnum.BUSINESS_ERROR);
        if (!AuditStateEnum.WAIT_AUDIT.getCode().equals(userAudit.getAuditStatus())) {
            throw new BusinessException("不可操作");
        }

        Integer auditType = auditOperateDTO.getAuditType();
        if (NumConsts.ONE.equals(auditType)) {
            userAuditService.passAudit(auditOperateDTO);
        } else if (NumConsts.TWO.equals(auditType)) {
            if (StringUtils.isBlank(auditOperateDTO.getAuditRemark())) {
                throw new BusinessException("驳回原因不可为空");
            }
            userAuditService.rejectAudit(auditOperateDTO);
        }

        return Result.success();
    }

    @Override
    public Result<List<LabelInfoVO>> queryContentCategoryLabels() {
        List<LevelLabelVO> list = labelInfoService.queryContentCategoryLabels(new QueryBrandModelLabelDTO());
        if (CollectionUtils.isEmpty(list)) {
            return Result.success(new ArrayList<>());
        }

        List<LabelInfoVO> voList = list.stream().map(vo -> {
            LabelInfoVO labelInfoVO = new LabelInfoVO();
            labelInfoVO.setLabelCode(vo.getLabelCode());
            labelInfoVO.setLabelName(vo.getLabelName());
            return labelInfoVO;
        }).collect(Collectors.toList());
        return Result.success(voList);
    }

    private QueryBusinessLabelListVO convertLabelVO(HeroLabelInfo labelInfo) {
        QueryBusinessLabelListVO vo = new QueryBusinessLabelListVO();
        vo.setLabelId(labelInfo.getId());
        vo.setLabelName(labelInfo.getLabelName());
        vo.setLabelIcon(labelInfo.getLabelIcon());
        vo.setLabelState(labelInfo.getLabelState());
        vo.setLabelStateName(LabelStateEnum.getNameByCode(labelInfo.getLabelState()));
        vo.setRelatedUserNums(labelInfo.getRelatedNum());
        vo.setCreaterUid(labelInfo.getCreateBy());
        vo.setCreateTime(labelInfo.getCreateTime());
        return vo;
    }

    private QueryBusinessLabelRelateVO convertQueryBusinessLabelRelateVO(QueryBusinessLabelRelatePO po,
        HeroLabelInfo labelInfo) {
        QueryBusinessLabelRelateVO queryBusinessLabelRelateVO = new QueryBusinessLabelRelateVO();
        queryBusinessLabelRelateVO.setLabelId(labelInfo.getId());
        queryBusinessLabelRelateVO.setLabelName(labelInfo.getLabelName());
        queryBusinessLabelRelateVO.setRelatedUid(po.getRelatedUid());
        queryBusinessLabelRelateVO.setNickname(po.getNickname());
        queryBusinessLabelRelateVO.setMobile(po.getMobile());
        queryBusinessLabelRelateVO.setUserState(po.getUserState());
        queryBusinessLabelRelateVO.setUserStateName(UserStateEnum.getNameByCode(po.getUserState()));
        queryBusinessLabelRelateVO.setRegistTime(po.getRegistTime());
        queryBusinessLabelRelateVO.setRelateTime(po.getRelateTime());
        queryBusinessLabelRelateVO.setRelateOperateUid(po.getRelateOperateUid());
        return queryBusinessLabelRelateVO;
    }

    private QueryAuditListVO convertQueryAuditListVO(HeroUserAudit heroUserAudit) {
        QueryAuditListVO queryAuditListVO = new QueryAuditListVO();
        queryAuditListVO.setAuditId(heroUserAudit.getId());
        queryAuditListVO.setApplicantUid(heroUserAudit.getApplyUid());
        queryAuditListVO.setAuditType(heroUserAudit.getAuditType());
        queryAuditListVO.setAuditTypeName(UserAuthTypeEnum.getNameByCode(heroUserAudit.getAuditType()));
        queryAuditListVO.setVerifiedLevel(heroUserAudit.getVerifiedLevel());
        //两种类型的图片材料都展示
        List<String> images = new ArrayList<>(StringUtil.str2List(heroUserAudit.getImages()));
        images.addAll(StringUtil.str2List(heroUserAudit.getPrivacyImages()));
        queryAuditListVO.setPlatformMobile(heroUserAudit.getPlatformMobile());
        queryAuditListVO.setImages(images);
        queryAuditListVO.setAuditState(heroUserAudit.getAuditStatus());
        queryAuditListVO.setAuditStateName(AuditStateEnum.getNameByCode(heroUserAudit.getAuditStatus()));
        queryAuditListVO.setAuditorUid(heroUserAudit.getAuditUid());
        queryAuditListVO.setApplyTime(heroUserAudit.getCreateTime());
        queryAuditListVO.setAuditTime(heroUserAudit.getAuditTime());
        return queryAuditListVO;
    }

    private QueryUserListVO convertQueryUserListVO(UserPO userPO) {
        QueryUserListVO queryUserListVO = new QueryUserListVO();
        queryUserListVO.setUid(userPO.getUid());
        queryUserListVO.setProfilePhoto(userPO.getProfilePhoto());
        queryUserListVO.setNickname(userPO.getNickname());
        queryUserListVO.setBindMobile(userPO.getMobile());
        queryUserListVO.setWechatNum(userPO.getWechatNum());
        queryUserListVO.setUserState(userPO.getUserState());
        queryUserListVO.setRegistTime(userPO.getCreateTime());
        queryUserListVO.setMemberLevel(userPO.getMemberLevel());
        queryUserListVO.setSettleTime(userPO.getSettleTime());
        return queryUserListVO;
    }
}
